/*!
//      
//      \file	k2k_X86IO.c
//      
//      \author	Copyright 2010 Valentina Vuksic <vuksv1@bfh.ch>, Beat Liechti <liecb2@bfh.ch>
//      
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.
//
//      Abstract Data Type for IO with the carme board
//      
//      \brief		CAS-EBX-03 Projektarbeit 
//      			Valentina Vuksic (VUKSV1), Beat Liechti (LIECB2)
//      			CarmeIO ADT for the k2k (Kaffee2000) application
//      \version	1.0
//      \date		2010-04-10
//      \remark		Last Modifications:
//      \remark  	v1.0, VUKSV1/LIECB2, 2010-04-10 Initial release
//
*/

#include <termios.h>
#include <unistd.h>
#include <stdio.h>

#include "k2k_X86IO.h"

/* -- static function declarations -----------------------------------*/

static int k2k_X86IO_NonBlockingGetChar();

/* -- ADT functions --------------------------------------------------*/

/*!
//
// Creates X86 IO ADT "object"
// 
// \return pointer to the X86 IO ADT
//
*/
k2k_X86IO* k2k_X86IO_Create()
{
	k2k_X86IO *x86IO = NULL;
	x86IO = malloc(sizeof(k2k_X86IO));
	if (x86IO != NULL)
	{
		/*! initialize structure */
		x86IO->ledState = 0;
	}
	return x86IO;
}

/*!
//
// Releases X86 IO ADT "object"
// 
// \param x86IO is the pointer to the X86 IO structure
// 
// \return noting
//
*/
void k2k_X86IO_Release(k2k_X86IO *x86IO)
{
	if (x86IO != NULL)
	{		
		/*! release memory */
		free(x86IO);	
	}
}

/*!
//
// Read LED pattern
// 
// \param x86IO is the pointer to the X86 IO structure
// \param pattern is the bitmap of the pattern for the LEDs
//
// \return bitmap of the status of the LEDs
//
*/
UINT8 k2k_X86IO_ReadLed(k2k_X86IO *x86IO)
{	
	return x86IO->ledState;
}

/*!
//
// Write LED pattern
// 
// \param x86IO is the pointer to the X86 IO structure
// \param pattern is the bitmap of the pattern for the LEDs
//
// \return nothing
//
*/
void k2k_X86IO_WriteLed(k2k_X86IO *x86IO, UINT8 pattern)
{	
	(pattern & 0x80) ? printf("1") : printf("0");
	(pattern & 0x40) ? printf("1") : printf("0");
	(pattern & 0x20) ? printf("1") : printf("0");
	(pattern & 0x10) ? printf("1") : printf("0");
	(pattern & 0x08) ? printf("1") : printf("0");
	(pattern & 0x04) ? printf("1") : printf("0");
	(pattern & 0x02) ? printf("1") : printf("0");
	(pattern & 0x01) ? printf("1") : printf("0");
	printf("\n");
	x86IO->ledState = pattern;
}

/*!
//
// Reads a button
// 
// \param x86IO is the pointer to the X86 IO structure
//
// \return next button in buffer
//
*/
int k2k_X86IO_ReadButton(k2k_X86IO *x86IO)
{	
	return k2k_X86IO_NonBlockingGetChar();	
}

/* -- static functions -----------------------------------------------*/

static int k2k_X86IO_NonBlockingGetChar()
{
	struct termios oldt,
	newt;
	int ch;
	tcgetattr( STDIN_FILENO, &oldt );
	newt = oldt;
	/*! turn off canonical mode */
	newt.c_lflag &= ~( ICANON | ECHO );
	/*! minimum of number input read */
	newt.c_cc[VMIN] = 0;
	tcsetattr( STDIN_FILENO, TCSANOW, &newt );
	ch = getchar();
	/*! turn on canonical mode */
	tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
	return ch;
}
